package org.lztvn.elearning.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.hibernate.dialect.FirebirdDialect;
import org.lztvn.elearning.entities.Friend;
import org.lztvn.elearning.entities.Message;
import org.lztvn.elearning.entities.User;
import org.lztvn.elearning.unityclass.Notify;
import org.lztvn.elearning.unityclass.RequestFriendUnity;
import org.springframework.transaction.annotation.Transactional;

public class FriendImpl implements IFriendDAO{
	@PersistenceContext
	EntityManager em;
	@Override
	@Transactional
	public Long addFriend(Friend friend) {
		em.persist(friend);
		em.flush();
		return friend.getId();
	}
	@Override
	public Map<String, List<Notify>> getAllRequestFriend(User user) {
		Map<String, List<Notify>> map =   new HashMap<String, List<Notify>>();
		//frien request
		Query q = em.createQuery("SELECT u FROM Friend u WHERE u.toUser = :fromA and u.status = false group by checked");
		q.setParameter("fromA", user.getIdUser());
		List<Notify> lstNotify = new ArrayList<Notify>();
		@SuppressWarnings("unchecked")
		List<Friend> lstFriend = (List<Friend>)q.getResultList();
		for (Friend friend : lstFriend) {
			Notify nf = new Notify();
			nf.fromUser = friend.getFromUser();
			nf.fromName = friend.getUserA().getFirstName();
			nf.fromPic = friend.getUserA().getPhoto();
			nf.toUser = user.getIdUser();
			nf.toName = user.getFirstName();
			nf.toPic = user.getPhoto();
			nf.check = friend.getChecked();
			lstNotify.add(nf);
		}
		if(lstNotify.size()>0){
		map.put("friend", lstNotify);
		}
		return map;
	}
	@Override
	@Transactional
	public void changeRequestFriendToChecked(Friend friendTemplate) {
		Friend friend = this.getFriendNotCheck(friendTemplate);
		friend.setChecked(true);
		em.merge(friend);
	}
	@Override
	public Friend getFriendNotCheck(Friend friendTemplate) {
		Query q = em.createQuery("SELECT u FROM Friend u WHERE u.fromUser = :fromA and u.toUser = :toA and u.status = false and checked=false");
		q.setParameter("fromA", friendTemplate.getFromUser());
		q.setParameter("toA", friendTemplate.getToUser());
		Friend result = (Friend)q.getSingleResult();
		return result;
	}
	@Override
	@Transactional
	public void changeRequestFriendStatus(Friend friendTemplate) {
		Friend friend = this.getNotFriend(friendTemplate);
		friend.setStatus(true);
		friend.setChecked(true);
		em.merge(friend);
	}
	@Override
	public Friend getNotFriend(Friend friendTemplate) {
		Query q = em.createQuery("SELECT u FROM Friend u WHERE u.fromUser = :fromA and u.toUser = :toA and u.status = false");
		q.setParameter("fromA", friendTemplate.getFromUser());
		q.setParameter("toA", friendTemplate.getToUser());
		Friend result = (Friend)q.getSingleResult();
		return result;
	}
	
	@Override
	public Map<String, List<Notify>> getAllMessage(User user) {
		Map<String, List<Notify>> map =   new HashMap<String, List<Notify>>();
		//frien request
		Query q = em.createQuery("SELECT u FROM Message u WHERE u.toUser = :fromA and u.status = false and u.orderMessage in (SELECT max(u.orderMessage) FROM Message u WHERE u.toUser = :fromA and u.status = false)");
		q.setParameter("fromA", user.getIdUser());
		List<Notify> lstNotify = new ArrayList<Notify>();
		@SuppressWarnings("unchecked")
		List<Message> lstFriend = (List<Message>)q.getResultList();
		for (Message message : lstFriend) {
			Notify nf = new Notify();
			nf.fromUser = message.getFromUser();
			nf.fromName = message.getUserA().getFirstName();
			nf.fromPic = message.getUserA().getPhoto();
			nf.toUser = user.getIdUser();
			nf.toName = user.getFirstName();
			nf.toPic = user.getPhoto();
			nf.message = message.getMessage();
			lstNotify.add(nf);
		}
		if(lstNotify.size()>0){
		map.put("message", lstNotify);
		}
		return map;
	}
	@Override
	public Map<String, List<Notify>> getAllMessageFromTo(
			RequestFriendUnity friend) {
		Map<String, List<Notify>> map =   new HashMap<String, List<Notify>>();
		//frien request
		Query q = em.createQuery("SELECT u FROM Message u WHERE (u.toUser = :fromA and u.fromUser = :fromB) or (u.toUser = :fromB and u.fromUser = :fromA) order by u.orderMessage DESC");
		q.setParameter("fromA", Long.parseLong(friend.getToUser()));
		q.setParameter("fromB", Long.parseLong(friend.getFromUser()));
		q.setMaxResults(5);
		List<Notify> lstNotify = new ArrayList<Notify>();
		@SuppressWarnings("unchecked")
		List<Message> lstFriend = (List<Message>)q.getResultList();
		for (Message message : lstFriend) {
			Notify nf = new Notify();
			nf.fromUser = message.getFromUser();
			nf.fromName = message.getUserA().getFirstName();
			nf.fromPic = message.getUserA().getPhoto();
			nf.toUser = message.getUserB().getIdUser();
			nf.toName = message.getUserB().getFirstName();
			nf.toPic = message.getUserB().getPhoto();
			nf.message = message.getMessage();
			nf.me = Long.parseLong(friend.getToUser());
			lstNotify.add(nf);
		}
		if(lstNotify.size()>0){
		map.put("message", lstNotify);
		}
		return map;
	}
	@Override
	@Transactional
	public void setAllMessageToRead(RequestFriendUnity friend) {
		// TODO Auto-generated method stub
		Query q = em.createQuery("UPDATE Message u SET u.status = true WHERE (u.toUser = :fromA and u.fromUser = :fromB)");
		q.setParameter("fromA", Long.parseLong(friend.getToUser()));
		q.setParameter("fromB", Long.parseLong(friend.getFromUser()));
		q.executeUpdate();
	}
}
